import './index.less'
import { Graph } from '@antv/g6';
import {isNil} from 'loadsh'
import {useEffect, useRef} from "react";
import useAppState from "../../store";

const AntG6 = () => {
    const {graphData, getState, setTriggerType, setTriggerId,similarTableData,triggerType} = useAppState();
    const splitRange = (value: number): number => {
        if (value < 500) return 0;
        else if (value < 1000) return 1;
        else if (value < 1500) return 2;
        else if (value < 2000) return 3;
        else return 4;
    }
    const graphRef=useRef(null);
    useEffect(() => {
        if(graphData.nodes.length===0) return;
        const tensile_strengths = graphData.nodes.map(item => item.data.Tensile_Strength)
        const max_tensile_strength = Math.max(...tensile_strengths);
        const yield_strengths = graphData.nodes.map(item => item.data.Yield_Strength)
        const max_yield_strength = Math.max(...yield_strengths);
        graphRef.current = new Graph({
            container: 'AntG6',
            autoFit: 'view',
            data: {
                nodes: graphData.nodes,
                edges: graphData.edges
            },
            animation: false,
            node: {
                type: 'donut',
                style: {
                    fill: '#D8E2EC',
                    // labelText:(d)=>
                    // {
                    //     return d.data.classification;
                    // },
                    // labelFill: 'black', // 标签文字颜色
                    // labelFontSize: 14, // 标签字体大小
                    // labelFontWeight: 'bolder', // 标签字体粗细
                    // labelPlacement: 'center', // 标签相对于节点主图形的位置
                    opacity: 1,
                    donuts: (item) => {
                        const greyColor = ["rgb(217,217,217)", "rgb(189,189,189)", "rgb(150,150,150)", "rgb(99,99,99)", "rgb(37,37,37)"];
                        const blueColor = ["rgb(208,209,230)", "rgb(166,189,219)", "rgb(116,169,207)", "rgb(43,140,190)", "rgb(4,90,141)"];
                        //圆环填充面积映射
                        const tensile_strength = item.data.Tensile_Strength * 100 / max_tensile_strength;
                        const yield_strength = item.data.Yield_Strength * 100 / max_yield_strength;
                        const BASE_VALUE = 0.01
                        //value不能为0，当为0的时候，会被忽略，所以当其为0的时候给其一个非常小的数
                        return [
                            {
                                value: yield_strength === 0 ? BASE_VALUE : yield_strength,
                                color: blueColor[splitRange(item.data.Yield_Strength)]
                            },
                            {value: 100 - yield_strength === 0 ? BASE_VALUE : 100 - yield_strength, color: 'white'},
                            {value: 100 - tensile_strength === 0 ? BASE_VALUE : 100 - tensile_strength, color: 'white'},
                            {
                                value: tensile_strength === 0 ? BASE_VALUE : tensile_strength,
                                color: greyColor[splitRange(item.data.Tensile_Strength)]
                            }
                        ];
                    },
                    donutStroke: "black"
                },
                state: {
                    selected: {
                        fill: "red"
                    },
                    neighborActive: {
                        fill: "#3B7CD6"
                    },
                    active: {
                        fill: "red"
                    },
                    defaultSelected:{
                        fill: "#7CFC00",
                        halo:'#7CFC00'
                    },
                    inRangeNodes:{
                        opacity:1
                    },
                    outOfRangeNodes:{
                        opacity:0.2
                    }
                },
            },
            edge: {
                style:{
                  opacity:1
                },
                // 边的状态样式
                state: {
                    selected: {
                        stroke: 'red',
                        lineWidth: 3,
                        opacity:1
                    },
                    active: {
                        lineWidth: 3,
                        stroke: 'red',
                        opacity:1
                    },
                    neighborActive: {
                        lineWidth: 3,
                        stroke: 'red',
                        opacity:1
                    },
                    selectRange:{
                        opacity:0.2
                    }
                }
            },
            layout: {
                type: 'force', // 速度衰减系数，控制收敛速度
                // clustering:true,
                // nodeClusterBy:'classification',
                // clusterNodeStrength:70
            },
            plugins: [
                {
                    type: 'tooltip',
                    getContent: (e, items) => {
                        //如果需要显示边提示框 则可以将下面注释放开
                        // if ("source" in items[0]) return `weight: ${items[0].data.weight}`;
                        if ("source" in items[0]) return;
                        else return `<h4>${items[0].data.ChemicalFormula}</h4>Tensile_Strength: ${items[0].data.Tensile_Strength}<br>Yield_Strength: ${items[0].data.Yield_Strength}`
                    },
                },
            ],
            behaviors: ['drag-canvas', 'zoom-canvas',
                {
                    type: 'hover-activate',
                    degree: 1
                },
                {
                    type: 'click-select',
                    degree: 1, // 选中扩散范围
                    neighborState: 'neighborActive', // 相邻节点附着状态
                    onClick: (event) => {
                        const {target} = event;
                        //当一个点或者一条边被重复点击的时候，清理状态
                        if (target.id === getState().triggerId) {
                            setTriggerType('');
                            setTriggerId('');
                            return;
                        }
                        if (target.type === "node" || target.type === "edge") {
                            setTriggerType(target.type);
                            setTriggerId(target.id);
                        } else {
                            setTriggerType('');
                            setTriggerId('');
                        }
                        console.log(target);
                    }
                },
            ],
        });
         const newNodeId=graphData.nodes.find(item=>item.data.NewNode===true)?.id;
         if(!isNil(newNodeId)){
             const defaultSelects={[newNodeId]:["defaultSelected","selected"]};
             graphData.edges.forEach(item=>{
                 if(item.target===newNodeId){
                     defaultSelects[item.source]="neighborActive";
                     defaultSelects[item.id]="neighborActive";
                 }
                 else if(item.source===newNodeId) {
                     defaultSelects[item.target]="neighborActive";
                     defaultSelects[item.id]="neighborActive";
                 }
             })
             setTriggerId(newNodeId);
             setTriggerType("node");
             graphRef.current.setElementState(defaultSelects);
         }
        graphRef.current.render();

        const colorSample = new Graph({
            container: 'ColorSample',
            autoFit: 'center',
            data: {
                nodes: [{
                    id: 'colorSample'
                }]
            },
            animation: false,
            node: {
                type: 'donut',
                style: {
                    fill: '#D8E2EC',
                    size: 60,
                    anchor: [0.5, 0.5],
                    donuts: (item) => {
                        const greyColor = ["rgb(217,217,217)", "rgb(189,189,189)", "rgb(150,150,150)", "rgb(99,99,99)", "rgb(37,37,37)"];
                        const blueColor = ["rgb(208,209,230)", "rgb(166,189,219)", "rgb(116,169,207)", "rgb(43,140,190)", "rgb(4,90,141)"];
                        return [
                            {value: 20, color: blueColor[0]},
                            {value: 20, color: blueColor[1]},
                            {value: 20, color: blueColor[2]},
                            {value: 20, color: blueColor[3]},
                            {value: 20, color: blueColor[4]},
                            {value: 20, color: greyColor[4]},
                            {value: 20, color: greyColor[3]},
                            {value: 20, color: greyColor[2]},
                            {value: 20, color: greyColor[1]},
                            {value: 20, color: greyColor[0]},
                        ];
                    },
                    donutStroke: "black"
                },
                state: {
                    active: {
                        fill: "red"
                    },
                },
            },
            plugins:[
                {
                    type: 'tooltip',
                    getContent: (e, items) => {
                        return `<h4>Tensile_Strength | Yield_Strength</h4>value<500<br>500<=value<1000<br>1000<=value<1500<br>1500<=value<2000<br>value>=2000`
                    },
                },
            ],
            layout: {
                type: 'force', // 速度衰减系数，控制收敛速度
            },
            behaviors:['hover-activate']
        })
        colorSample.render()
        return () => {
            graphRef.current.destroy();
            colorSample.destroy();
        }
    }, [graphData]);
    // 过滤函数
    const filterElements = (arr,state) => {
        arr.map(element=>{
            const tempStates=element.states.filter(item=>item!==state);
            graphRef.current.setElementState(element.id,tempStates);
        })
    };
    const resetGraphStates=()=>{
        // 获取所有处于指定状态的节点数据
        const selectedNodes = graphRef.current.getElementDataByState('node', 'selected');
        filterElements(selectedNodes,"selected");
        const neighborActiveNodes=graphRef.current.getElementDataByState('node', 'neighborActive');
        filterElements(neighborActiveNodes,"neighborActive");
        const selectedEdges = graphRef.current.getElementDataByState('edge', 'selected');
        filterElements(selectedEdges,"selected");
        const neighborActiveEdges=graphRef.current.getElementDataByState('edge', 'neighborActive');
        filterElements(neighborActiveEdges,"neighborActive");

        //节点状态清除
        const inRangeNodes=graphRef.current.getElementDataByState('node', 'inRangeNodes');
        filterElements(inRangeNodes,"inRangeNodes");
        const outOfRangeNodes=graphRef.current.getElementDataByState('node', 'outOfRangeNodes');
        filterElements(outOfRangeNodes,"outOfRangeNodes");
    }
    useEffect(() => {
        if(triggerType==="selectRange") {
            resetGraphStates();
            //节点区间状态添加
            const stateUpdate={};
            const similarTableDataId=similarTableData.map(item=>item.id);
            graphData.nodes.map(item=>{
                if(similarTableDataId.includes(item.id)){
                    stateUpdate[item.id]="inRangeNodes";
                }else {
                    stateUpdate[item.id]="outOfRangeNodes";
                }
            })
            const newNodeId=graphData.nodes.find(item=>item.data.NewNode===true)?.id;
            if(!isNil(newNodeId)){
                const tempNodeState=stateUpdate[newNodeId];
                stateUpdate[newNodeId]=[tempNodeState,"defaultSelected"]
            }
            graphData.edges.map((item)=>{
                stateUpdate[item.id]="selectRange";
            })
            graphRef.current.setElementState(stateUpdate);
        }else if(triggerType==="undoRange"){
            resetGraphStates();
            //节点区间状态添加
            const stateUpdate={};
            graphData.edges.map((item)=>{
                stateUpdate[item.id]=[];
            })
            graphRef.current.setElementState(stateUpdate);
        }
    }, [similarTableData]);
    return (
        <>
            <div id={"AntG6"}>
                <div id={"ColorSample"}></div>
            </div>
        </>
    )
}
export default AntG6;
